package xg.glycomaid.utils;

import java.io.*;
import java.util.Vector;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;

// Referenced classes of package org.eurocarbdb.application.glycanbuilder:
//            LogUtils

public class XMLUtils
{

    public XMLUtils()
    {
    }

    public static Document newDocument()
    {
        try
        {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            return builder.newDocument();
        }
        catch(Exception e)
        {
            LogUtils.report(e);
        }
        return null;
    }

    public static Document read(String data)
    {
        try
        {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            return builder.parse(new ByteArrayInputStream(data.getBytes()));
        }
        catch(Exception e)
        {
            LogUtils.report(e);
        }
        return null;
    }

    public static Document read(byte data[])
    {
        try
        {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            return builder.parse(new ByteArrayInputStream(data));
        }
        catch(Exception e)
        {
            LogUtils.report(e);
        }
        return null;
    }

    public static Document read(InputStream is)
    {
        try
        {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            return builder.parse(is);
        }
        catch(Exception e)
        {
            LogUtils.report(e);
        }
        return null;
    }

    public static boolean write(OutputStream os, Document d)
    {
        if(os == null || d == null)
            return false;
        try
        {
            TransformerFactory tFactory = TransformerFactory.newInstance();
            Transformer transformer = tFactory.newTransformer();
            transformer.setOutputProperty("indent", "yes");
            DOMSource source = new DOMSource(d);
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
            StreamResult result = new StreamResult(bw);
            transformer.transform(source, result);
            return true;
        }
        catch(Exception e)
        {
            LogUtils.report(e);
        }
        return false;
    }

    public static Node findChild(Node node, String child_name)
    {
        if(node == null)
            return null;
        NodeList children = node.getChildNodes();
        for(int i = 0; i < children.getLength(); i++)
        {
            Node child = children.item(i);
            if(child.getNodeName().equals(child_name))
                return child;
        }

        return null;
    }

    public static Node assertChild(Node node, String child_name)
        throws Exception
    {
        Node ret = findChild(node, child_name);
        if(ret == null)
            throw new Exception((new StringBuilder()).append("Cannot find ").append(child_name).append(" node").toString());
        else
            return ret;
    }

    public static Vector findAllChildren(Node node)
    {
        if(node == null)
            return null;
        Vector found_children = new Vector();
        NodeList children = node.getChildNodes();
        for(int i = 0; i < children.getLength(); i++)
        {
            Node child = children.item(i);
            if(child.getNodeType() == 1)
                found_children.add(child);
        }

        return found_children;
    }

    public static Vector findAllChildren(Node node, String child_name)
    {
        if(node == null)
            return null;
        Vector found_children = new Vector();
        NodeList children = node.getChildNodes();
        for(int i = 0; i < children.getLength(); i++)
        {
            Node child = children.item(i);
            if(child.getNodeName().equals(child_name))
                found_children.add(child);
        }

        return found_children;
    }

    public static Node findChildAssertive(Node node, String child_name)
    {
        if(node == null)
            return null;
        Node child = findChild(node, child_name);
        if(child != null)
            return child;
        else
            return node.appendChild(node.getOwnerDocument().createElement(child_name));
    }

    public static void setText(Node node, String value)
    {
        if(node == null)
            return;
        Node child = findChild(node, "#text");
        if(child == null)
            node.appendChild(node.getOwnerDocument().createTextNode(value));
        else
            child.setNodeValue(value);
    }

    public static String getText(Node node)
    {
        if(node == null)
            return null;
        Node child = findChild(node, "#text");
        if(child == null)
            return null;
        else
            return child.getNodeValue();
    }

    public static String getAttribute(Node node, String att_name)
    {
        if(node == null)
            return "";
        else
            return getText(node.getAttributes().getNamedItem(att_name));
    }

    public static Integer getIntegerAttribute(Node node, String att_name)
    {
        if(node == null)
            return null;
        String text = getText(node.getAttributes().getNamedItem(att_name));
        if(text == null)
            return null;
        else
            return Integer.valueOf(text);
    }

    public static Double getDoubleAttribute(Node node, String att_name)
    {
        if(node == null)
            return null;
        String text = getText(node.getAttributes().getNamedItem(att_name));
        if(text == null)
            return null;
        else
            return Double.valueOf(text);
    }

    public static Boolean getBooleanAttribute(Node node, String att_name)
    {
        if(node == null)
            return null;
        String text = getText(node.getAttributes().getNamedItem(att_name));
        if(text == null)
            return null;
        else
            return Boolean.valueOf(text);
    }
}
